File: //proc/self/root/opt/alt/python37/lib/python3.7/site-packages/clpackages/clquota_packages_lib.py
# -*- coding: utf-8 -*-
# clquota_packages_lib.py - module for interfacing with lvectl utility for get/set package inodes limits
#
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT
from __future__ import absolute_import
import csv
from cllimits.lib import exec_utility
from cllimits import ClQuotaException
from cllimits.lib.utils import is_quota_supported, is_quota_active
class ClQuotaPackage(object):
def __init__(self):
self._CL_QUOTA_PATH = '/usr/bin/cl-quota'
self._REPQUOTA_PATH = '/usr/sbin/repquota'
# Error flag
self._is_clquota_error = False
# Check if quota is supported
self._is_clquota_present = is_quota_supported(self._CL_QUOTA_PATH, self._REPQUOTA_PATH)
# Check if quota is activated
self._is_clquota_activated = is_quota_active(self._CL_QUOTA_PATH, self._REPQUOTA_PATH)
# indodes packages limits dictionary: {package_name: { "soft": 100000, "hard": 200000 } }
self._inode_package_dict = None
def is_clquota_present(self):
"""
Get cl-quota presence flag
:return: Quota utilities presence flag
"""
return self._is_clquota_present
def is_clquota_activated(self):
"""
Get quota activated flag
:return: True/False - quotas present/not present
"""
return self._is_clquota_activated
def _load_info(self):
"""
Loads packages info from cl-quota
:return: None
"""
# Exit if cl-quota data already loaded
if self._inode_package_dict is not None:
return
disabled_exc_message = {'message': "%(util)s is disabled",
'context': {'util': 'Quota'}}
# Exit if cl-quota not present or cl-quota error
if not self._is_clquota_present or not self._is_clquota_activated or self._is_clquota_error:
raise ClQuotaException(disabled_exc_message)
# Get all cl-quota limits and parse them to self._inodes_limits
# /usr/bin/cl-quota --all-package-limits --csv
ret_code, s_quota_limits = exec_utility(self._CL_QUOTA_PATH, ['--csv', '--all-package-limits'])
if ret_code != 0:
# Error
self._is_clquota_error = True
raise ClQuotaException(disabled_exc_message)
reader = csv.reader(s_quota_limits.split('\n'), delimiter=',')
self._inode_package_dict = dict()
header_found = False
for row in reader:
if 'ERROR' in row:
# Error
self._is_clquota_error = True
# Remove data dictionary
self._inode_package_dict = None
raise ClQuotaException(disabled_exc_message)
# Pass 1st line - header
if not header_found:
header_found = True
continue
# Put data to result dictionary
if row[2] == '-':
soft_limit = 0
else:
soft_limit = int(row[2])
if row[3] == '-':
hard_limit = 0
else:
hard_limit = int(row[3])
self._inode_package_dict[row[0]] = {'soft': soft_limit, 'hard': hard_limit}
def get_reseller_package_limits(self, package_name_arg):
"""
Get inodes limits for supplied reseller and package
:param package_name_arg: Package name. Only if reseller name is provided. If None - all packages
:return: Packages limits dictionary: {package_name: { "soft": 100000, "hard": 200000 } }
If package with supplied name not found, dictionary will be empty
"""
self._load_info()
if not package_name_arg:
# if package name not provided - return all packages
return self._inode_package_dict
# Package name provided
if package_name_arg in self._inode_package_dict:
return {package_name_arg: self._inode_package_dict[package_name_arg]}
return {}
def __set_error(self, param, package_name, err):
return {'message': "%(what)s set error for package=%(package)s%(error)s",
'context': {'what': param, 'package': package_name,
'error': " [%s]" % err if err else ""}}
def set_reseller_package_limits(self, package_name, limits_to_set):
"""
Set inodes limits for package
:param package_name: Package name
:param limits_to_set: Limits to set: soft_limit,hard_limit
:return: None
"""
disabled_exc_message = {'message': "%(util)s is disabled",
'context': {'util': 'Quota'}}
# Exit if cl-quota not present or cl-quota error
if not self._is_clquota_present or not self._is_clquota_activated:
raise ClQuotaException(disabled_exc_message)
limits = limits_to_set.split(',')
if len(limits) != 2:
# Argument error
raise ClQuotaException({'message': "%(util)s argument error",
'context': {'util': 'cl-quota'}})
# set quotas limits
cl_quota_cmd = ['--package=%s' % package_name,
'--soft=%s' % limits[0], '--hard=%s' % limits[1]]
ret_code, stdout = exec_utility(self._CL_QUOTA_PATH, cl_quota_cmd)
if ret_code != 0 or stdout:
# Set limits error
raise ClQuotaException(self.__set_error('Inodes limits', package_name, stdout))